package com.erytech.linktalk.web.client.datasource;

import com.erytech.linktalk.web.client.framework.DataSource;
import com.erytech.linktalk.web.client.service.EndpointUtil;
import com.erytech.linktalk.web.client.service.MessageInfo;
import com.erytech.linktalk.web.client.service.MessageRpcService;
import com.erytech.linktalk.web.client.service.MessageRpcServiceAsync;
import com.erytech.linktalk.web.client.service.UserInfo;
import com.google.gwt.core.client.GWT;
import com.google.gwt.user.client.Timer;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.rpc.InvocationException;
import com.google.gwt.user.client.rpc.ServiceDefTarget;

public class MessageDataSource extends DataSource {

	private Timer timer;
	
	private RoomDataSource roomDataSource;

	private MessageRpcServiceAsync messageRpc;

	public MessageDataSource(RoomDataSource roomDataSource) {
		this.roomDataSource = roomDataSource;
	}
	
	public RoomDataSource getRoomDataSource() {
		return roomDataSource;
	}

	public void startPolling() {
		getTimer().scheduleRepeating(2000);
	}

	public void stopChating() {
		getTimer().cancel();
	}

	public void postMsg(final MessageInfo messageInfo) {
		UserInfo userInfo = getRoomDataSource().getUserDataSource().getUserInfo();
		messageInfo.setFrom(userInfo.getName());
		messageInfo.setRoomId(userInfo.getRoomId());
		messageInfo.setTo(getRoomDataSource().getUserDataSource().getSaidTo());
		getMessageRpc().postMessage(messageInfo, new AsyncCallback() {
			public void onSuccess(Object obj) {
				fireDataUpdateEvent(new MessageUpdateEvent(MessageDataSource.this, 
						MessageUpdateEvent.POST_SUCCESS, new MessageInfo[]{messageInfo}));
				pollMessages();
			}
			public void onFailure(Throwable t) {
				handleInvocationFailure(t);
				fireDataUpdateEvent(new MessageUpdateEvent(MessageDataSource.this, 
						MessageUpdateEvent.POST_FAILURE, t));
			}
		});
	}

	private void pollMessages() {
		getMessageRpc().getMessages(new AsyncCallback() {
			public void onSuccess(Object obj) {
				fireDataUpdateEvent(new MessageUpdateEvent(MessageDataSource.this, 
						MessageUpdateEvent.POLL_SUCCESS, (MessageInfo[]) obj));
			}

			public void onFailure(Throwable t) {
				handleInvocationFailure(t);
				fireDataUpdateEvent(new MessageUpdateEvent(MessageDataSource.this, 
						MessageUpdateEvent.POLL_FAILURE, t));
			}
		});
	}

	private void handleInvocationFailure(Throwable t) {
		if(t instanceof InvocationException) {
			timer.cancel();
		}
	}
	
	private Timer getTimer() {
		if(timer == null) {
			timer = new Timer() {
				public void run() {
					pollMessages();
				}
			};
		}
		return timer;
	}

	private MessageRpcServiceAsync getMessageRpc() {
		if (messageRpc == null) {
			messageRpc = (MessageRpcServiceAsync) GWT
					.create(MessageRpcService.class);
			((ServiceDefTarget) messageRpc).setServiceEntryPoint(EndpointUtil
					.getRealEndPoint("/message.rpc"));
		}
		return messageRpc;
	}

}